package com.wudgaby.spring.shiro.bean;

import java.util.Optional;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.wudgaby.spring.shiro.domain.User;
import com.wudgaby.spring.shiro.service.UserService;

public class ShiroRealm extends AuthorizingRealm {
    private static final Logger log = LoggerFactory.getLogger(SecondRealm.class);
    @Autowired private UserService userService;

    /**
     * 认证
     * token 来至用户输入
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {

        log.info("{}", "first realm is working.");

        String userName = (String)token.getPrincipal();

        //user from db
        Optional<User> userOp = userService.findByUserName(userName);
        User user = userOp.orElseThrow(AuthenticationException::new);

        ByteSource salt = ByteSource.Util.bytes(userName);

        SimpleHash simpleHash = new SimpleHash("MD5", user.getPassword(), salt, 5);

        return new SimpleAuthenticationInfo(user.getUserName(), simpleHash.toHex(), salt, getName());
    }

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection priCollection) {
        Optional<User> userOp = userService.findByUserName(priCollection.toString());
        User user = userOp.orElseGet(User::new);

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(user.getRoles());
        return info;
    }
}
